/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.scene.service.impl;


import com.koron.common.bean.StaffBean;
import com.koron.common.dfs.FastDFSClientWrapper;
import com.koron.common.domain.DataBean;
import com.koron.common.web.Util;
import com.koron.scene.domain.ProjectCertificate;
import com.koron.scene.domain.ProjectStaff;
import com.koron.scene.domain.ProjectTraining;
import com.koron.scene.mapper.ProjectCertificateMapper;
import com.koron.scene.mapper.ProjectStaffMapper;
import com.koron.scene.mapper.ProjectTrainingMapper;
import com.koron.scene.service.api.ProjectStaffService;
import com.koron.scene.utils.BaseEntityUtil;
import com.koron.scene.utils.BusinessCode;
import com.koron.scene.utils.DateUtil;
import com.koron.scene.utils.ExcelUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.swan.bean.MessageBean;

import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ProjectStaffServiceImpl implements ProjectStaffService {

    private static final Logger logger = LoggerFactory.getLogger(ProjectStaffServiceImpl.class);

    @Autowired
    private FastDFSClientWrapper clientWrapper;

    @Autowired
    private Util util;

    @Override
    public MessageBean<?> importExcel(StaffBean user, MultipartFile file, String projectId, String enterpriseId) {
        MessageBean<?> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), Object.class);
        if (StringUtils.isBlank(projectId) || StringUtils.isBlank(enterpriseId)) {
            msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
            msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
            return msg;
        }
        String filePath = null;
        SessionFactory factory = new SessionFactory();
        try {
            ProjectStaffMapper mapper = factory.getMapper(ProjectStaffMapper.class);
            //先将文件上传到文件服务器
            if (null == file) {
                msg.setCode(22001);
                msg.setDescription("上传文件为空");
                return msg;
            }
            String fileName = file.getOriginalFilename();
            filePath = clientWrapper.uploadFile(file) + "#" + fileName;//文件上传的路径
            //处理excel中的内容
            InputStream inputStream = file.getInputStream();
            XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
            if (null == workbook) {
                logger.error("上传文件为空");
                msg.setCode(22001);
                msg.setDescription("上传文件为空");
                return msg;
            }
            XSSFSheet sheet = workbook.getSheetAt(0);
            if (sheet == null) {
                logger.error("上传文件为空");
                msg.setCode(22001);
                msg.setDescription("上传文件为空");
                return msg;
            }
            List<ProjectStaff> projectStaffList = new ArrayList<>();
            int rowsNum = sheet.getPhysicalNumberOfRows();
            for (int i = 1; i < rowsNum; i++) {
                XSSFRow row = sheet.getRow(i);
                ProjectStaff staff = parseRow(row, user, projectId, enterpriseId);
                if (staff != null) {
                    projectStaffList.add(staff);
                }
            }
            if (projectStaffList != null && projectStaffList.size() > 0) {
                Date now = new Date();
                List<ProjectStaff> insertList = new ArrayList<>();
                //新项目人员list 去重
                List<String> distIdNumberList = new ArrayList<>();
                List<ProjectStaff> distinctList = new ArrayList<>();
                for (ProjectStaff projectStaff : projectStaffList) {
                    if (!distIdNumberList.contains(projectStaff.getIdCardNumber())) {
                        distIdNumberList.add(projectStaff.getIdCardNumber());
                        distinctList.add(projectStaff);
                    }
                }
                //项目当前人员
                List<ProjectStaff> orgProjectStaffList = mapper.queryList(projectId, enterpriseId, 0, null, null, null);
                List<String> sameList = new ArrayList<>();
                if (orgProjectStaffList != null && orgProjectStaffList.size() > 0) {
                    //去除重复的保存成历史
                    for (ProjectStaff orgProjectStaff : orgProjectStaffList) {
                        for (ProjectStaff newProjectStaff : distinctList) {
                            //已存在的更新
                            if (orgProjectStaff.getIdCardNumber().equals(newProjectStaff.getIdCardNumber())) {
                                ProjectStaff projectStaff = new ProjectStaff();
                                projectStaff.setId(orgProjectStaff.getId());
                                projectStaff.setName(newProjectStaff.getName());
                                projectStaff.setSex(newProjectStaff.getSex());
                                projectStaff.setPhoneNumber(newProjectStaff.getPhoneNumber());
                                projectStaff.setJoinDate(newProjectStaff.getJoinDate());
                                projectStaff.setExitDate(newProjectStaff.getExitDate());
                                BaseEntityUtil.setUpdateBaseProperties(projectStaff, user);
                                mapper.updateByPrimaryKeySelective(projectStaff);
                                sameList.add(orgProjectStaff.getIdCardNumber());
                            }
                        }
                    }
                    insertList = distinctList.stream().filter(projectStaff -> !sameList.contains(projectStaff.getIdCardNumber())).collect(Collectors.toList());
                    if (orgProjectStaffList != null && orgProjectStaffList.size() > 0) {
                        List<ProjectStaff> historyIdList = orgProjectStaffList.stream().filter(projectStaff -> {
                            return !sameList.contains(projectStaff.getIdCardNumber());
                        }).collect(Collectors.toList());

                        if (historyIdList != null && historyIdList.size() > 0) {
                            //历史人员
                            for (ProjectStaff history : historyIdList) {
                                ProjectStaff projectStaff = new ProjectStaff();
                                projectStaff.setId(history.getId());
                                projectStaff.setHistoryFlag(1);
                                if (history.getExitDate() == null) {
                                    projectStaff.setExitDate(now);
                                }
                                BaseEntityUtil.setUpdateBaseProperties(projectStaff, user);
                                mapper.updateByPrimaryKeySelective(projectStaff);
                            }
                        }
                    }
                } else {
                    insertList = distinctList;
                }
                if (insertList != null && insertList.size() > 0) {
                    //新增人员
                    mapper.insertList(insertList);
                }
            }
        } catch (
                Exception e) {
            if (!StringUtils.isEmpty(filePath)) {
                clientWrapper.deleteFile(filePath.split("#")[0]);
            }
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
            factory.close(false);
        } finally {
            if (factory != null) {
                factory.close();
            }
        }
        return msg;
    }

    @Override
    public MessageBean<?> update(StaffBean user, String staffId, String name, String phoneNumber, String joinDateStr, String exitDateStr) {
        MessageBean<?> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), Object.class);
        SessionFactory factory = new SessionFactory();
        try {
            ProjectStaffMapper projectMapper = factory.getMapper(ProjectStaffMapper.class);
            if (StringUtils.isBlank(staffId)) {
                msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
                msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
                return msg;
            }
            ProjectStaff staff = new ProjectStaff();
            staff.setPhoneNumber(phoneNumber);
            staff.setExitDate(DateUtil.formatStringToDate(exitDateStr, DateUtil.DATE_FORMAT_YMD));
            staff.setJoinDate(DateUtil.formatStringToDate(joinDateStr, DateUtil.DATE_FORMAT_YMD));
            staff.setName(name);
            staff.setId(staffId);
            BaseEntityUtil.setUpdateBaseProperties(staff, user);
            projectMapper.updateByPrimaryKeySelective(staff);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
            factory.close(false);
            return msg;
        } finally {
            if (factory != null) {
                factory.close();
            }
        }
        return msg;
    }

    @Override
    public MessageBean<?> list(StaffBean user, String projectId, String enterpriseId, Integer historyFlag, String name, Integer page, Integer pageSize) {
        MessageBean<DataBean> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), DataBean.class);
        try (SessionFactory factory = new SessionFactory()) {
            ProjectStaffMapper projectStaffMapper = factory.getMapper(ProjectStaffMapper.class);
            Integer start = null;
            if (page != null && pageSize != null && page > 0 && pageSize > 0) {
                start = (page - 1) * pageSize;
            }
            List<ProjectStaff> list = projectStaffMapper.queryList(projectId, enterpriseId, historyFlag, name, start, pageSize);
            int total = projectStaffMapper.queryListTotal(projectId, enterpriseId, historyFlag, name);
            DataBean dataBean = new DataBean();
            dataBean.setList(list);
            dataBean.setTotalNumber(total);
            dataBean.setPageNo(page);
            dataBean.setPageSize(pageSize);
            dataBean.setTotalPage(start == null ? null : total % pageSize == 0 ? total / pageSize : (total / pageSize + 1));
            msg.setData(dataBean);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
        }
        return msg;
    }

    void setProjectStaffPropoties(List<ProjectStaff> list, ProjectStaffMapper projectStaffMapper) {
        Date now = new Date();
        for (ProjectStaff projectStaff : list) {
            if (projectStaff != null) {
//                List <ProjectStaff> staffList=projectStaffMapper.queryByIdCardNumber(projectStaff.getIdCardNumber(), null, null);
                if (projectStaff.getWorkState() != null && projectStaff.getWorkState() == 1) {
                    projectStaff.setLastWorkDate(now);
                } else {
                    projectStaff.setLastWorkDate(projectStaff.getExitDate());
                }
            }
        }
    }

    @Override
    public MessageBean<?> managementList(StaffBean user, String staffName, String enterpriseName, String projectName, Integer page, Integer pageSize, String corpCode,String keyword) {
        MessageBean<DataBean> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), DataBean.class);
        try (SessionFactory factory = new SessionFactory()) {
            ProjectStaffMapper projectStaffMapper = factory.getMapper(ProjectStaffMapper.class);
            Integer start = null;
            if (page != null && pageSize != null && page > 0 && pageSize > 0) {
                start = (page - 1) * pageSize;
            }
            String codes = util.getDeptCodes(corpCode);
            List<ProjectStaff> list = projectStaffMapper.managementList(staffName, enterpriseName, projectName, start, pageSize, codes,keyword);
            if (list != null && list.size() > 0) {
                setProjectStaffPropoties(list, projectStaffMapper);
            }
            int total = projectStaffMapper.managementListTotal(staffName, enterpriseName, projectName, codes,keyword);
            DataBean dataBean = new DataBean();
            dataBean.setList(list);
            dataBean.setTotalNumber(total);
            dataBean.setPageNo(page);
            dataBean.setPageSize(pageSize);
            dataBean.setTotalPage(start == null ? null : total % pageSize == 0 ? total / pageSize : (total / pageSize + 1));
            msg.setData(dataBean);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
        }
        return msg;
    }

    @Override
    public MessageBean<?> staffProjectList(StaffBean user, String idCardNumber, String corpCode, Integer page, Integer pageSize) {
        MessageBean<DataBean> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), DataBean.class);
        if (StringUtils.isBlank(idCardNumber) || StringUtils.isBlank(corpCode)) {
            msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
            msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
            return msg;
        }
        try (SessionFactory factory = new SessionFactory()) {
            ProjectStaffMapper projectStaffMapper = factory.getMapper(ProjectStaffMapper.class);
            Integer start = null;
            if (page != null && pageSize != null && page > 0 && pageSize > 0) {
                start = (page - 1) * pageSize;
            }
            List<ProjectStaff> list = projectStaffMapper.queryByIdCardNumber(idCardNumber, corpCode, start, pageSize);
            if (list != null && list.size() > 0) {
                setStaffCertificateAndTraining(list);
            }
            int total = projectStaffMapper.queryByIdCardNumberTotal(idCardNumber, corpCode);
            DataBean dataBean = new DataBean();
            dataBean.setList(list);
            dataBean.setTotalNumber(total);
            dataBean.setPageNo(page);
            dataBean.setPageSize(pageSize);
            dataBean.setTotalPage(start == null ? null : total % pageSize == 0 ? total / pageSize : (total / pageSize + 1));
            msg.setData(dataBean);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
        }
        return msg;
    }

    @Override
    public List<ProjectStaff> exportList(StaffBean user, String corpCode, String staffName, String enterpriseName, String projectName) {
        try (SessionFactory factory = new SessionFactory()) {
            ProjectStaffMapper projectStaffMapper = factory.getMapper(ProjectStaffMapper.class);
            String codes = util.getDeptCodes(corpCode);
            List<ProjectStaff> list = projectStaffMapper.managementList(staffName, enterpriseName, projectName, null, null, codes,null);
            if (list != null && list.size() > 0) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                setProjectStaffPropoties(list, projectStaffMapper);
                list.forEach(bean -> {
                    if (null != bean.getLastWorkDate()) {
                        bean.setLastWorkDateStr(sdf.format(bean.getLastWorkDate()));
                    }
                });
            }
            return list;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            return null;
        }
    }

    @Override
    public MessageBean<?> oneStaffProject(StaffBean user, String idCardNumber, String corpCode, String projectStaffId) {
        MessageBean<ProjectStaff> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), ProjectStaff.class);
        if (StringUtils.isBlank(idCardNumber) || StringUtils.isBlank(corpCode)) {
            msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
            msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
            return msg;
        }
        try (SessionFactory factory = new SessionFactory()) {
            ProjectStaffMapper projectStaffMapper = factory.getMapper(ProjectStaffMapper.class);
            ProjectStaff projectStaff = projectStaffMapper.queryByIdAndIdCardNumber(idCardNumber, corpCode, projectStaffId);
            if (projectStaff != null) {
                ProjectCertificateMapper certificateMapper = factory.getMapper(ProjectCertificateMapper.class);
                ProjectTrainingMapper trainingMapper = factory.getMapper(ProjectTrainingMapper.class);
                //查询证书
                List<ProjectCertificate> certificateList = certificateMapper.queryByProjectAndIdCardNumber(projectStaff.getProjectId(), projectStaff.getIdCardNumber());
                //查询培训
                List<ProjectTraining> trainingList = trainingMapper.queryByProjectAndIdCardNumber(projectStaff.getProjectId(), projectStaff.getIdCardNumber());
                projectStaff.setProjectCertificateList(certificateList);
                projectStaff.setProjectTrainingList(trainingList);
            }
            msg.setData(projectStaff);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
        }
        return msg;
    }


    void setStaffCertificateAndTraining(List<ProjectStaff> list) {
        try (SessionFactory factory = new SessionFactory()) {
            ProjectCertificateMapper certificateMapper = factory.getMapper(ProjectCertificateMapper.class);
            ProjectTrainingMapper trainingMapper = factory.getMapper(ProjectTrainingMapper.class);
            for (ProjectStaff projectStaff : list) {
                if (projectStaff != null) {
                    //查询证书
                    List<ProjectCertificate> certificateList = certificateMapper.queryByProjectAndIdCardNumber(projectStaff.getProjectId(), projectStaff.getIdCardNumber());
                    //查询培训
                    List<ProjectTraining> trainingList = trainingMapper.queryByProjectAndIdCardNumber(projectStaff.getProjectId(), projectStaff.getIdCardNumber());
                    projectStaff.setProjectCertificateList(certificateList);
                    projectStaff.setProjectTrainingList(trainingList);
                }
            }
        }

    }

    //行转换
    private ProjectStaff parseRow(XSSFRow row, StaffBean user, String projectId, String enterpriseId)
            throws Exception {
        ProjectStaff staff = new ProjectStaff();
//        人员
        String name = ExcelUtil.getCellValue(row.getCell(0));
//        性别
        String sexStr = ExcelUtil.getCellValue(row.getCell(1));
//        项目名称
        String projectNameStr = ExcelUtil.getCellValue(row.getCell(2));
//        相关方单位
        String enterpriseNameStr = ExcelUtil.getCellValue(row.getCell(3));
//        身份证
        XSSFCell cell = row.getCell(4);
        String idCardNumber = ExcelUtil.getCellValue(cell);
        if (cell != null && cell.getCellTypeEnum() == CellType.NUMERIC) {
            BigDecimal db = new BigDecimal(idCardNumber);
            idCardNumber = db.toPlainString();
        }
//        电话
        XSSFCell cell1 = row.getCell(5);
        String phoneNumber = ExcelUtil.getCellValue(cell1);
        if (cell1 != null && cell1.getCellTypeEnum() == CellType.NUMERIC) {
            BigDecimal db = new BigDecimal(phoneNumber);
            phoneNumber = db.toPlainString();
        }
//        加入时间
        String joinDateStr = ExcelUtil.getCellValue(row.getCell(6));
//                退出时间
        String exitDateStr = ExcelUtil.getCellValue(row.getCell(7));
        if (StringUtils.isBlank(name)) {
            return null;
        } else {
            staff.setName(name);
        }
        if ("女".equals(sexStr)) {
            staff.setSex(0);
        } else if ("男".equals(sexStr)) {
            staff.setSex(1);
        } else {
            return null;
        }
//        if (StringUtils.isBlank(projectNameStr)) {
//
//        }
//        if (StringUtils.isBlank(projectNameStr)) {
//
//        }
        if (StringUtils.isBlank(idCardNumber)) {
            return null;
        } else {
            staff.setIdCardNumber(idCardNumber);
        }
        Date now = new Date();
        Date joinDate = DateUtil.formatStringToDate(joinDateStr, DateUtil.DATE_FORMAT_YMD);
        if (joinDate == null) {
            staff.setJoinDate(now);
        } else {
            staff.setJoinDate(joinDate);
        }
        Date exitDate = DateUtil.formatStringToDate(exitDateStr, DateUtil.DATE_FORMAT_YMD);
        if (exitDate != null && joinDate.before(exitDate)) {
            staff.setExitDate(exitDate);
        }
        staff.setEnterpriseId(enterpriseId);
        staff.setProjectId(projectId);
        staff.setPhoneNumber(phoneNumber);
        staff.setHistoryFlag(0);
        BaseEntityUtil.setAddBaseProperties(staff, user);
        return staff;
    }
}
